package com.ev.k3cloudBusiness.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ev.common.enums.AuditStatusDict;
import com.ev.custom.dao.DictionaryDao;
import com.ev.custom.domain.DictionaryDO;
import com.ev.custom.domain.MaterielDO;
import com.ev.custom.domain.MaterielTypeDO;
import com.ev.custom.domain.SupplierDO;
import com.ev.custom.service.MaterielService;
import com.ev.custom.service.SupplierService;
import com.ev.framework.utils.R;
import com.ev.framework.utils.ShiroUtils;
import com.ev.hr.domain.EmployeeInfoDO;
import com.ev.hr.service.EmployeeInfoService;
import com.ev.k3cloud.entity.K3CloudBillQueryEntity;
import com.ev.k3cloud.enums.K3CloudBillFormId;
import com.ev.k3cloud.service.K3CloudService;
import com.ev.k3cloudBusiness.service.K3PurchaseOrderSynService;
import com.ev.k3cloudBusiness.vo.K3MaterialResultsVo;
import com.ev.k3cloudBusiness.vo.K3PurchaseOrderEntryResultsVo;
import com.ev.k3cloudBusiness.vo.K3PurchaseOrderResultsVo;
import com.ev.scm.domain.PurchasecontractDO;
import com.ev.scm.domain.PurchasecontractItemDO;
import com.ev.scm.service.PurchasecontractItemService;
import com.ev.scm.service.PurchasecontractService;
import com.ev.system.domain.DeptDO;
import com.ev.system.domain.UserDO;
import com.ev.system.service.DeptService;
import com.ev.system.service.UserService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class K3PurchaseOrderSynServiceImpl implements K3PurchaseOrderSynService {
    private static final String PURCHASE_TYPE = "contract_type";
    private static final Long PURCHASE_TYPE_ID = 54L;
    @Autowired
    K3CloudService k3CloudService;
    @Autowired
    PurchasecontractService purchasecontractService;
    @Autowired
    PurchasecontractItemService purchasecontractItemService;
    @Autowired
    DictionaryDao dictionaryDao;
    @Autowired
    SupplierService supplierService;
    @Autowired
    DeptService deptService;
    @Autowired
    EmployeeInfoService employeeInfoService;
    @Autowired
    MaterielService materielService;
    @Autowired
    UserService userService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R PurchaseOrderSyn(){
        //查询芯软云采购合同
        List<PurchasecontractDO> purchasecontractDOList=purchasecontractService.listAll();
        List<PurchasecontractItemDO> purchasecontractItemDOList=purchasecontractItemService.listAll();
        //调用K3Cloud采购订单单据查询接口查询已审核未关闭采购订单
        K3CloudBillQueryEntity k3CloudBillQueryEntity=new K3CloudBillQueryEntity();
        k3CloudBillQueryEntity.setFormId(K3CloudBillFormId.PUR_PURCHASEORDER.getFormId());
        k3CloudBillQueryEntity.setFieldKeys("FID,FBillNo,FDate,FSupplierId.FNUMBER,FPurchaserId.FNUMBER,FPurchaseDeptId.FNUMBER,FPurchaseOrgId.FNUMBER,FBillTypeID.FNUMBER,FBillTypeID,FBillTypeID.FNAME,FPOOrderEntry_FEntryID ,FMaterialId.FNUMBER,FQty,FPurchaserId.FNAME,FPurchaserId,FSupplierId,FPurchaseDeptId,FMaterialId ");
        k3CloudBillQueryEntity.setFilterString("FDocumentStatus='C' and FCloseStatus='A' and FMaterialId.FNUMBER is not null ");
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("data", k3CloudBillQueryEntity);
        String materialResult=k3CloudService.billQuery(JSON.toJSONString(dataMap));
        JSONArray resultObj = JSON.parseArray(materialResult);
        if(materialResult.contains("ResponseStatus"))
        {
            if( !resultObj.getJSONArray(0).getJSONObject(0).getJSONObject("Result").getJSONObject("ResponseStatus").getBooleanValue("IsSuccess") ) {
                log.info(resultObj.getJSONArray(0).getJSONObject(0).getJSONObject("Result").getJSONObject("ResponseStatus").getJSONArray("Errors").toString());
                return R.error(resultObj.getJSONArray(0).getJSONObject(0).getJSONObject("Result").getJSONObject("ResponseStatus").getJSONArray("Errors").toString());
            }
        }

        List<K3PurchaseOrderEntryResultsVo> purchaseOrderEntryResultsVos=new ArrayList<>();
        List<K3PurchaseOrderResultsVo> purchaseOrderResultsVos=new ArrayList<>();
        for (int i=0;i<resultObj.size();i++)
        {
            JSONArray Obj=resultObj.getJSONArray(i);
            K3PurchaseOrderEntryResultsVo  purchaseOrderEntryResultsVo= new K3PurchaseOrderEntryResultsVo();
            K3PurchaseOrderResultsVo  purchaseOrderOne= new K3PurchaseOrderResultsVo();
            purchaseOrderOne.setFID(Obj.getLong(0));
            purchaseOrderOne.setFBILLNO(Obj.getString(1));
            purchaseOrderOne.setFDATE(Obj.getDate(2));
            purchaseOrderOne.setSUPPLIERNUMBER(Obj.getString(3));
            purchaseOrderOne.setPURCHASENUMBER(Obj.getString(4));
            purchaseOrderOne.setPURCHASEDEPTNUMBER(Obj.getString(5));
            purchaseOrderOne.setPURCHASEORGNUMBER(Obj.getString(6));
            purchaseOrderOne.setBILLTYPENUMBER(Obj.getString(7));
            purchaseOrderOne.setBILLTYPEID(Obj.getString(8));
            purchaseOrderOne.setBILLTYPENAME(Obj.getString(9));
            purchaseOrderOne.setPURCHASENAME(Obj.getString(13));
            purchaseOrderOne.setPURCHASEID(Obj.getLong(14));
            purchaseOrderOne.setSUPPLIERID(Obj.getLong(15));
            purchaseOrderOne.setPURCHASEDEPTID(Obj.getLong(16));
            purchaseOrderResultsVos.add(purchaseOrderOne);
            purchaseOrderEntryResultsVo.setFID(Obj.getLong(0));
            purchaseOrderEntryResultsVo.setENTRYID(Obj.getLong(10));
            purchaseOrderEntryResultsVo.setMATERIALNUMBER(Obj.getString(11));
            purchaseOrderEntryResultsVo.setQTY(Obj.getBigDecimal(12));
            purchaseOrderEntryResultsVo.setMATERIALID(Obj.getLong(17));
            purchaseOrderEntryResultsVos.add(purchaseOrderEntryResultsVo);
        }
        if(purchaseOrderResultsVos.size() > 0)
        {
            purchaseOrderResultsVos=purchaseOrderResultsVos.stream().distinct().collect(Collectors.toList());
            long okAudit = AuditStatusDict.OK_AUDIT.getId();
            Long userId = ShiroUtils.getUserId();
            Map<String,Object> param = Maps.newHashMap();
            // 获取本地所有的采购合同类型
            List<DictionaryDO> localPurChaseList = dictionaryDao.listByType(PURCHASE_TYPE);
            this.handle(purchaseOrderResultsVos,localPurChaseList);
            Map<String, Long> localPurChaseMap = localPurChaseList.stream().distinct().collect(Collectors.toMap(DictionaryDO::getName, DictionaryDO::getId, (v1, v2) -> v1));
            // 本地采购订单内码
            List<Long> localIdList = purchasecontractDOList.stream().map(PurchasecontractDO::getId).collect(Collectors.toList());
            // K3Cloud采购订单内码
            List<Long> remoteIdList = purchaseOrderResultsVos.stream().map(K3PurchaseOrderResultsVo::getFID).collect(Collectors.toList());
            // 删除的 k3无，本地有
            List<Long> deleteIdList = localIdList.stream().filter(e -> !remoteIdList.contains(e)).collect(Collectors.toList());
            // 修改的（本地库有的，远端库有的）
            List<Long> updateIdList = remoteIdList.stream().filter(localIdList::contains).collect(Collectors.toList());
            // 新增的（本地库无的，远端库有的）
            remoteIdList.removeAll(updateIdList);
            if(deleteIdList.size()>0)
            {
                //批量删除
                List<PurchasecontractDO> purchasecontractDOS=purchasecontractDOList.stream().filter(e->deleteIdList.contains(e.getId())).collect(Collectors.toList());
                for (PurchasecontractDO purchasecontractDO:purchasecontractDOS
                ) {
                    purchasecontractDO.setDelFlag(1);
                }
                purchasecontractService.batchUpdate(purchasecontractDOS);
                log.info("批量删除");
            }
            if(updateIdList.size()>0)
            {

                //查询芯软云部门
                List<DeptDO> deptDOList=deptService.listForAll();
                //查询芯软云供应商
                List<SupplierDO> supplierDOS=supplierService.listAll();
                List<EmployeeInfoDO> employeeInfoDOList ;
                List<DeptDO> deptDOS;
                List<SupplierDO> supplierDOList;
                List<UserDO> userDOS;
                //批量更新
                List<K3PurchaseOrderResultsVo> k3PurchaseOrderResultsVoList = purchaseOrderResultsVos.stream().filter(e -> updateIdList.contains(e.getFID())).collect(Collectors.toList());
                List<PurchasecontractDO> purchasecontractDOSUpdate=purchasecontractDOList.stream().filter(e->updateIdList.contains(e.getId())).collect(Collectors.toList());
                for (PurchasecontractDO purchasecontractDO:purchasecontractDOSUpdate
                ) {
                    K3PurchaseOrderResultsVo purchaseOrderResultsVo=k3PurchaseOrderResultsVoList.stream().filter(e->(purchasecontractDO.getId().equals(e.getFID()))).collect(Collectors.toList()).get(0);
                    //单据编号
                    purchasecontractDO.setContractCode(purchaseOrderResultsVo.getFBILLNO());
                    //单据日期
                    purchasecontractDO.setContractDate(purchaseOrderResultsVo.getFDATE());
                    supplierDOList=supplierDOS.stream().filter(e-> e.getId().equals(purchaseOrderResultsVo.getSUPPLIERID())).collect(Collectors.toList());
                    if(supplierDOList.size()==0)
                    {
                        return R.error("请同步供应商");
                    }
                    //供应商ID
                    purchasecontractDO.setSupplierId(supplierDOList.get(0).getId());
                    //供应商代码
                    purchasecontractDO.setSupplierContractCode(purchaseOrderResultsVo.getSUPPLIERNUMBER());

                    //采购员ID
                    purchasecontractDO.setBuyer(1L);
                    //采购部门ID
                    deptDOS=deptDOList.stream().filter(e-> e.getDeptId().equals(purchaseOrderResultsVo.getPURCHASEDEPTID())).collect(Collectors.toList());
                    if(deptDOS.size()==0)
                    {
                        return R.error("请同步部门");
                    }
                    purchasecontractDO.setDeptId(deptDOS.get(0).getDeptId());
                    //采购组织
                    purchasecontractDO.setOrgNumber(purchaseOrderResultsVo.getPURCHASEORGNUMBER());
                    //单据类型ID
                    purchasecontractDO.setContractType(localPurChaseMap.get(purchaseOrderResultsVo.getBILLTYPENAME()));
                    purchasecontractDO.setAuditSign(okAudit);
                    purchasecontractDO.setAuditor(userId);
                    purchasecontractDO.setDelFlag(0);
                }
                purchasecontractService.batchUpdate(purchasecontractDOSUpdate);
                log.info("批量更新");
            }
            if(remoteIdList.size()>0)
            {

                //查询芯软云部门
                List<DeptDO> deptDOList=deptService.listForAll();
                //查询芯软云供应商
                List<SupplierDO> supplierDOS=supplierService.listAll();
                List<EmployeeInfoDO> employeeInfoDOList ;
                List<DeptDO> deptDOS ;
                List<SupplierDO> supplierDOList ;
                List<UserDO> userDOS;
                //批量插入
                List<K3PurchaseOrderResultsVo> k3PurchaseOrderResultsVoList = purchaseOrderResultsVos.stream().filter(e -> remoteIdList.contains(e.getFID())).collect(Collectors.toList());
                List<PurchasecontractDO> purchasecontractDOS= Lists.newArrayList();
                for (K3PurchaseOrderResultsVo k3PurchaseOrderResultsVo:k3PurchaseOrderResultsVoList
                ) {
                    PurchasecontractDO purchasecontractDO=new PurchasecontractDO();
                    //单据内码
                    purchasecontractDO.setId(k3PurchaseOrderResultsVo.getFID());
                    //单据编号
                    purchasecontractDO.setContractCode(k3PurchaseOrderResultsVo.getFBILLNO());
                    //单据日期
                    purchasecontractDO.setContractDate(k3PurchaseOrderResultsVo.getFDATE());
                    supplierDOList=supplierDOS.stream().filter(e-> e.getId().equals(k3PurchaseOrderResultsVo.getSUPPLIERID())).collect(Collectors.toList());
                    if(supplierDOList.size()==0)
                    {
                        return R.error("请同步供应商");
                    }
                    //供应商ID
                    purchasecontractDO.setSupplierId(supplierDOList.get(0).getId());
                    //供应商代码
                    purchasecontractDO.setSupplierContractCode(k3PurchaseOrderResultsVo.getSUPPLIERNUMBER());

                    //采购员ID
                    purchasecontractDO.setBuyer(1L);
                    purchasecontractDO.setCloseStatus(0);
                    //采购部门ID
                    deptDOS=deptDOList.stream().filter(e-> e.getDeptId().equals(k3PurchaseOrderResultsVo.getPURCHASEDEPTID())).collect(Collectors.toList());
                    if(deptDOS.size()==0)
                    {
                        return R.error("请同步部门");
                    }
                    purchasecontractDO.setDeptId(deptDOS.get(0).getDeptId());
                    //采购组织
                    purchasecontractDO.setOrgNumber(k3PurchaseOrderResultsVo.getPURCHASEORGNUMBER());
                    //单据类型ID
                    purchasecontractDO.setContractType(localPurChaseMap.get(k3PurchaseOrderResultsVo.getBILLTYPENAME()));
                    purchasecontractDO.setAuditSign(okAudit);
                    purchasecontractDO.setAuditor(userId);
                    purchasecontractDO.setDelFlag(0);
                    purchasecontractDOS.add(purchasecontractDO);
                }
                purchasecontractService.batchSave(purchasecontractDOS);
                log.info("批量新增");
            }
            //同步采购订单明细
            // 本地采购订单明细
            List<Long> localIdEnitityList = purchasecontractItemDOList.stream().map(PurchasecontractItemDO::getId).collect(Collectors.toList());
            // K3Cloud采购订单明细内码
            List<Long> remoteIdEnitityList = purchaseOrderEntryResultsVos.stream().map(K3PurchaseOrderEntryResultsVo::getENTRYID).collect(Collectors.toList());
            // 删除的 k3无，本地有
            List<Long> deleteIdEnitityList = localIdEnitityList.stream().filter(e -> !remoteIdEnitityList.contains(e)).collect(Collectors.toList());
            // 修改的（本地库有的，远端库有的）
            List<Long> updateIdEnitityList = remoteIdEnitityList.stream().filter(localIdEnitityList::contains).collect(Collectors.toList());
            // 新增的（本地库无的，远端库有的）
            remoteIdList.removeAll(updateIdList);
            if(deleteIdEnitityList.size()>0)
            {
                //批量删除
                List<PurchasecontractItemDO> purchasecontractItemDOS=purchasecontractItemDOList.stream().filter(e->deleteIdEnitityList.contains(e.getId())).collect(Collectors.toList());
                for (PurchasecontractItemDO purchasecontractDOS:purchasecontractItemDOS
                ) {
                    purchasecontractDOS.setDelFlag(1);
                }
                purchasecontractItemService.batchUpdate(purchasecontractItemDOS);
                log.info("批量删除");
            }
            if(updateIdEnitityList.size()>0)
            {
                //查询芯软云物料
                List<MaterielDO> materielDOList=materielService.listForAll();
                List<MaterielDO> materielDOS = new ArrayList<>();
                //批量更新
                List<K3PurchaseOrderEntryResultsVo> k3PurchaseOrderEntryResultsVoList = purchaseOrderEntryResultsVos.stream().filter(e -> updateIdEnitityList.contains(e.getENTRYID())).collect(Collectors.toList());
                List<PurchasecontractItemDO> purchasecontractItemUpdate=purchasecontractItemDOList.stream().filter(e->updateIdEnitityList.contains(e.getId())).collect(Collectors.toList());
                for (PurchasecontractItemDO purchasecontractItemDO:purchasecontractItemUpdate
                ) {
                    K3PurchaseOrderEntryResultsVo purchaseOrderEntryResultsVo=k3PurchaseOrderEntryResultsVoList.stream().filter(e->(purchasecontractItemDO.getId().equals(e.getENTRYID()))).collect(Collectors.toList()).get(0);
                    //物料ID
                    materielDOS=materielDOList.stream().filter(e-> e.getId().equals(purchaseOrderEntryResultsVo.getMATERIALID())).collect(Collectors.toList());
                    if(materielDOS.size()==0)
                    {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return R.error("请同步物料");
                    }
                    purchasecontractItemDO.setMaterielId(materielDOS.get(0).getId());
                    //数量
                    purchasecontractItemDO.setCount(purchaseOrderEntryResultsVo.getQTY());
                    purchasecontractItemDO.setDelFlag(0);
                }
                purchasecontractItemService.batchUpdate(purchasecontractItemUpdate);
                log.info("批量更新");
            }
            if(remoteIdEnitityList.size()>0)
            {
                //查询芯软云物料
                List<MaterielDO> materielDOList=materielService.listForAll();
                List<MaterielDO> materielDOS = new ArrayList<>();
                //批量插入
                List<K3PurchaseOrderEntryResultsVo> k3PurchaseOrderEntryResultsVoList = purchaseOrderEntryResultsVos.stream().filter(e -> remoteIdEnitityList.contains(e.getENTRYID())).collect(Collectors.toList());
                List<PurchasecontractItemDO> purchasecontractItemDOS= Lists.newArrayList();
                for (K3PurchaseOrderEntryResultsVo k3PurchaseOrderResultsVoList:k3PurchaseOrderEntryResultsVoList
                ) {
                    PurchasecontractItemDO purchasecontractItemDO=new PurchasecontractItemDO();
                    //明细内码
                    purchasecontractItemDO.setId(k3PurchaseOrderResultsVoList.getENTRYID());
                    //明细关联ID
                    purchasecontractItemDO.setPurchaseContractId(k3PurchaseOrderResultsVoList.getFID());
                    //物料ID
                    materielDOS=materielDOList.stream().filter(e-> e.getId().equals(k3PurchaseOrderResultsVoList.getMATERIALID())).collect(Collectors.toList());
                    if(materielDOS.size()==0)
                    {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return R.error("请同步物料");
                    }
                    purchasecontractItemDO.setMaterielId(materielDOS.get(0).getId());
                    //数量
                    purchasecontractItemDO.setCount(k3PurchaseOrderResultsVoList.getQTY());
                    purchasecontractItemDO.setIsCheck(1);
                    purchasecontractItemDO.setIsOvercharge(0);
                    purchasecontractItemDO.setDelFlag(0);
                    purchasecontractItemDOS.add(purchasecontractItemDO);
                }
                purchasecontractItemService.batchSave(purchasecontractItemDOS);
                log.info("批量新增");
            }
        }
        return R.ok();
    }
    private void handle(List<K3PurchaseOrderResultsVo> remoteData, List<DictionaryDO> localPurChaseList) {

        List<String> localPurChaseNameList = localPurChaseList.stream().map(DictionaryDO::getName).collect(Collectors.toList());

        // 获取远端所有的采购合同类型
        List<String> remotePurChaseNameList = remoteData.stream().map(K3PurchaseOrderResultsVo::getBILLTYPENAME).distinct().collect(Collectors.toList());

        List<DictionaryDO> savePurChaseList = Lists.newArrayList();

        remotePurChaseNameList.removeAll(localPurChaseNameList);

        if (remotePurChaseNameList.size() > 0) {
            DictionaryDO dictDO;
            for (String s : remotePurChaseNameList) {
                dictDO = new DictionaryDO();
                dictDO.setName(s);
                dictDO.setTypeId(PURCHASE_TYPE_ID);
                dictDO.setKingeeNumber(remoteData.stream().filter(e->e.getBILLTYPENAME().equals(s)).collect(Collectors.toList()).get(0).getBILLTYPENUMBER());
                savePurChaseList.add(dictDO);
            }
        }
        if (savePurChaseList.size() > 0) {
            // 批量保存
            dictionaryDao.batchSave(savePurChaseList);
            localPurChaseList.addAll(savePurChaseList);
        }
    }
}
